﻿using GalaSoft.MvvmLight;
using System;
using System.Linq;
using System.Collections.ObjectModel;
using System.Windows.Input;

namespace CochonMVVM.Stocks
{
    public class CustomStock : Stock
    {
        public int Id { get; set; }
        public int ArticleId { get; set; }
        public int Qte { get; set; }
        public string Designation { get; set; }
        public DateTime DateCommande { get; set; }

        public CustomStock() { }

        public CustomStock(Stock s)
        {
            Id = s.Id;
            ArticleId = s.ArticleId;
            Qte = s.Qte;
        }
    }

    public class StockViewModel : ViewModelBase
    {
        private double PRODUCTION_PAR_JOUR_SEC = 720;
        private double PRODUCTION_PAR_JOUR_NOIX = 355;
        private const double QTE_SEL = 0.0225;
        private const double QTE_AIL = 0.1;
        private const double QTE_EPICE = 0.02;
        private const double QTE_NOIX = 0.5;

        //private readonly IDataService _dataService;
        private static CochonMCDDataContext dataContext = new CochonMCDDataContext();

        #region Properties

        private ObservableCollection<Stock> stockCollection = new ObservableCollection<Stock>();

        public ObservableCollection<Stock> StockCollection
        {
            get { return stockCollection; }
            set
            {
                if (stockCollection != value)
                {
                    stockCollection = value;
                    RaisePropertyChanged(() => StockCollection);
                }
            }
        }

        private ObservableCollection<CustomStock> customStockCollection = new ObservableCollection<CustomStock>();

        public ObservableCollection<CustomStock> CustomStockCollection
        {
            get { return customStockCollection; }
            set
            {
                if (customStockCollection != value)
                {
                    customStockCollection = value;
                    RaisePropertyChanged(() => CustomStockCollection);
                }
            }
        }

        private DateTime dateDebut = new DateTime(2011, 1, 1);

        public DateTime DateDebut
        {
            get { return dateDebut; }
            set
            {
                if (dateDebut != value)
                {
                    dateDebut = value;
                    RaisePropertyChanged(() => dateDebut);
                }
            }
        }

        private double majoration;

        public double Majoration
        {
            get { return majoration; }
            set
            {
                if (majoration != value)
                {
                    majoration = value;
                    RaisePropertyChanged(() => Majoration);
                }
            }
        }

        private string articleDesignation;

        public string ArticleDesignation
        {
            get { return articleDesignation; }
            set
            {
                if (articleDesignation != value)
                {
                    articleDesignation = value;
                    RaisePropertyChanged(() => ArticleDesignation);
                }
            }
        }

        #endregion

        #region Commandes

        private DelegateCommand<object> calculerDatesCommand;

        public ICommand CalculerDatesCommand
        {
            get { return calculerDatesCommand; }
        }

        #endregion Commandes

        #region InitializeData

        /// <summary>
        /// Récupération des stocks existants en BDD
        /// </summary>
        private void InitializeData()
        {       
            PRODUCTION_PAR_JOUR_SEC = dataContext.Prevision.FirstOrDefault(pjs => pjs.Nom == "PJS").Valeur.Value;
            PRODUCTION_PAR_JOUR_NOIX = dataContext.Prevision.FirstOrDefault(pjsn => pjsn.Nom == "PJSN").Valeur.Value;
            PRODUCTION_PAR_JOUR_SEC = PRODUCTION_PAR_JOUR_SEC + PRODUCTION_PAR_JOUR_SEC * (Majoration / 100);
            PRODUCTION_PAR_JOUR_NOIX = PRODUCTION_PAR_JOUR_NOIX + PRODUCTION_PAR_JOUR_NOIX * (Majoration / 100);
            double nbJours = 0;
            customStockCollection.Clear();

            foreach (Stock currentStock in dataContext.Stock)
            {
                Article art = dataContext.Article.Where(ar => ar.Id == currentStock.ArticleId).FirstOrDefault();

                // Soi c'est un ingrédient
                if (art.Type)
                {
                    // On récup la première composition (pour la QTE) de l'ingrédient
                    Composition comp = dataContext.Composition.Where(co => co.ArticleId == art.Id).FirstOrDefault();

                    if (comp != null)
                    {
                        double productionParJour = 0;

                        if (art.Designation != "Noix")
                        {
                            productionParJour = PRODUCTION_PAR_JOUR_SEC + PRODUCTION_PAR_JOUR_NOIX;
                        }
                        else
                        {
                            productionParJour = PRODUCTION_PAR_JOUR_NOIX;
                        }
                        // (stock - production d'une semaine) / production journalière
                        nbJours = (double)currentStock.Qte
                            / (double)((productionParJour) * comp.Qte);
                        // On soustrait les 5 jours de délais
                        nbJours -= 5;
                        //nbJours = (double)(currentStock.Qte - ((PRODUCTION_PAR_JOUR_SEC + PRODUCTION_PAR_JOUR_NOIX) * comp.Qte * 5))
                        //    / (double)((PRODUCTION_PAR_JOUR_SEC + PRODUCTION_PAR_JOUR_NOIX) * comp.Qte);

                    }


                    CustomStock cs = new CustomStock
                    {
                        Id = currentStock.Id,
                        ArticleId = currentStock.ArticleId,
                        Qte = currentStock.Qte,
                        Designation = art.Designation,
                        DateCommande = AddBusinessDays(DateDebut, (int)Math.Ceiling(nbJours))
                    };
                    CustomStockCollection.Add(cs);
                }
            }
            RaisePropertyChanged(() => CustomStockCollection);
        }

        #endregion

        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        public StockViewModel()
        {
            InitializeData();

            calculerDatesCommand = new DelegateCommand<object>(
                obj =>
                {
                    InitializeData();
                });
        }

        public DateTime AddBusinessDays(DateTime dt, int nDays)
        {
            int weeks = nDays / 5;
            nDays %= 5;
            while (dt.DayOfWeek == DayOfWeek.Saturday || dt.DayOfWeek == DayOfWeek.Sunday)
                dt = dt.AddDays(1);

            while (nDays-- > 0)
            {
                dt = dt.AddDays(1);
                if (dt.DayOfWeek == DayOfWeek.Saturday)
                    dt = dt.AddDays(2);
            }
            return dt.AddDays(weeks * 7);
        }
    }
}